package cn.doitedu.rulemk.demos;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
核心元字符：
$	匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性，则 $ 也匹配 '\n' 或 '\r'。
( )	标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。
*	匹配前面的子表达式零次或多次。
+	匹配前面的子表达式一次或多次。
.	匹配除换行符 \n 之外的任何单字符。
[	标记一个中括号表达式的开始。
?	匹配前面的子表达式零次或一次，或指明一个非贪婪限定符。
\	将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如， 'n' 匹配字符 'n'。'\n' 匹配换行符。序列 '\\' 匹配 "\"，而 '\(' 则匹配 "("。
^	匹配输入字符串的开始位置，除非在方括号表达式中使用，当该符号在方括号表达式中使用时，表示不接受该方括号表达式中的字符集合。
{	标记限定符表达式的开始。
|	指明两项之间的一个选择。

核心限定符：
*	匹配前面的子表达式零次或多次。例如，zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,}。
+	匹配前面的子表达式一次或多次。例如，'zo+' 能匹配 "zo" 以及 "zoo"，但不能匹配 "z"。+ 等价于 {1,}。
?	匹配前面的子表达式零次或一次。例如，"do(es)?" 可以匹配 "do" 、 "does" 中的 "does" 、 "doxy" 中的 "do" 。? 等价于 {0,1}。
{n}	n 是一个非负整数。匹配确定的 n 次。例如，'o{2}' 不能匹配 "Bob" 中的 'o'，但是能匹配 "food" 中的两个 o。
{n,}	n 是一个非负整数。至少匹配n 次。例如，'o{2,}' 不能匹配 "Bob" 中的 'o'，但能匹配 "foooood" 中的所有 o。'o{1,}' 等价于 'o+'。'o{0,}' 则等价于 'o*'。
{n,m}	m 和 n 均为非负整数，其中n <= m。最少匹配 n 次且最多匹配 m 次。例如，"o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。请注意在逗号和两个数之间不能有空格。




常用表达式举例：
 * 非负整数：^\d+$
 * 正整数：^[0-9]*[1-9][0-9]*$
 * 非正整数：^((-\d+)|(0+))$
 * 负整数：^-[0-9]*[1-9][0-9]*$
 * 整数：^-?\d+$
 * 非负浮点数：^\d+(\.\d+)?$
 * 正浮点数 : ^((0-9)+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)$
 * 非正浮点数：^((-\d+\.\d+)?)|(0+(\.0+)?))$
 * 负浮点数：^(-((正浮点数正则式)))$
 * 英文字符串：^[A-Za-z]+$
 * 英文大写串：^[A-Z]+$
 * 英文小写串：^[a-z]+$
 * 英文字符数字串：^[A-Za-z0-9]+$
 * 英数字加下划线串：^\w+$
 * E-mail地址：^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$
 * URL：^[a-zA-Z]+://(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\s*)?$
 * 或：^http:\/\/[A-Za-z0-9]+\.[A-Za-z0-9]+[\/=\?%\-&_~`@[\]\':+!]*([^<>\"\"])*$
 * 邮政编码：^[1-9]\d{5}$
 * 中文：^[\u0391-\uFFE5]+$
 * 电话号码：^((\(\d{2,3}\))|(\d{3}\-))?(\(0\d{2,3}\)|0\d{2,3}-)?[1-9]\d{6,7}(\-\d{1,4})?$
 * 手机号码：^((\(\d{2,3}\))|(\d{3}\-))?13\d{9}$
 * 双字节字符(包括汉字在内)：^\x00-\xff
 * 匹配首尾空格：(^\s*)|(\s*$)（像vbscript那样的trim函数）
 * 匹配HTML标记：<(.*)>.*<\/\1>|<(.*) \/>
 * 匹配空行：\n[\s| ]*\r
 * 提取信息中的网络链接：(h|H)(r|R)(e|E)(f|F) *= *('|")?(\w|\\|\/|\.)+('|"| *|>)?
 * 提取信息中的邮件地址：\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
 * 提取信息中的图片链接：(s|S)(r|R)(c|C) *= *('|")?(\w|\\|\/|\.)+('|"| *|>)?
 * 提取信息中的IP地址：(\d+)\.(\d+)\.(\d+)\.(\d+)
 * 提取信息中的中国手机号码：(86)*0*13\d{9}
 * 提取信息中的中国固定电话号码：(\(\d{3,4}\)|\d{3,4}-|\s)?\d{8}
 * 提取信息中的中国电话号码（包括移动和固定电话）：(\(\d{3,4}\)|\d{3,4}-|\s)?\d{7,14}
 * 提取信息中的中国邮政编码：[1-9]{1}(\d+){5}
 * 提取信息中的浮点数（即小数）：(-?\d*)\.?\d+
 * 提取信息中的任何数字 ：(-?\d*)(\.\d+)?
 * IP：(\d+)\.(\d+)\.(\d+)\.(\d+)
 * 电话区号：/^0\d{2,3}$/
 * 腾讯QQ号：^[1-9]*[1-9][0-9]*$
 * 帐号(字母开头，允许5-16字节，允许字母数字下划线)：^[a-zA-Z][a-zA-Z0-9_]{4,15}$
 * 中文、英文、数字及下划线：^[\u4e00-\u9fa5_a-zA-Z0-9]+$
 * 匹配中文字符的正则表达式： [\u4e00-\u9fa5]
 * 匹配双字节字符(包括汉字在内)：[^\x00-\xff]
 * 匹配空行的正则表达式：\n[\s| ]*\r
 * 匹配HTML标记的正则表达式：/<(.*)>.*<\/\1>|<(.*) \/>/
 * sql语句：^(select|drop|delete|create|update|insert).*$
 * 匹配首尾空格的正则表达式：(^\s*)|(\s*$)
 * 匹配Email地址的正则表达式：\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
 */
public class RegexExpressionDemo {

    public static void main(String[] args) {


        // 目标字符串
        String sequenceStr = "15312343323323233332";

        // 正则表达式（pattern）
        String p;
        // p = "1.*3.*5";      // 做过1,任意事件后做过3,任意事件后做过5
        // p = "12.*3";        // 做过1紧跟2，任意事件后做过3
        // p = "1(\\d{5})2";   // 做过 1,2且之间隔了5个任意事件
        // p = "1(\\d+)2";     // 做过 1,2且之间隔了至少1个别的事件
        // p = "12{3}.*3";     // 做过1后紧跟做了三次2，任意事件后做过3
        // p = "12{2,3}3";     // 做过1后紧跟做了2-3次2，后紧接着做过3
        // p = "1(?!2).*3";    // 做过1,后面做过3,中间不能发生2
        // p = "1(?![24]).*3"; // 做过1,后面做过3,中间不能发生2或者4
         p = "1(?=[35]).*2";   // 做过1,后面紧跟着做过3或者5,再之后任意事件后做过2

        // 正则匹配计算
        Pattern r = Pattern.compile(p);
        Matcher matcher = r.matcher(sequenceStr);
        int count = 0;
        while (matcher.find()) {
            count++;
        }

        System.out.println(count);

    }
}
